# LeetCode 387、字符串中的第一个唯一字符

# 一、题目描述

给定一个字符串 s ,找到 它的第一个不重复的字符,并返回它的索引 。如果不存在,则返回 -1

示例 1:

输入: s = "leetcode"

输出: 0

示例 2:

输入: s = "loveleetcode"

输出: 2

示例 3:

输入: s = "aabb"

输出: -1

提示:

  • 1 <= s.length <= 10^5
  • s 只包含小写字母

# 二、题目解析

# 三、参考代码

class Solution {
    public int firstUniqChar(String s) {
        Map<Character, Integer> counter = new HashMap<>();
        
        // 统计字符频率
        for (char c : s.toCharArray()) {
            counter.put(c, counter.getOrDefault(c, 0) + 1);
        }
        
        // 找到第一个出现频率为 1 的字符
        for (int i = 0; i < s.length(); i++) {
            if (counter.get(s.charAt(i)) == 1) {
                return i;
            }
        }
        
        // 不存在唯一字符,返回 -1
        return -1;
    }
}
class Solution {
public:
    int firstUniqChar(string s) {
        unordered_map<char, int> counter;
        
        // 统计字符频率
        for (char c : s) {
            counter[c]++;
        }
        
        // 找到第一个出现频率为 1 的字符
        for (int i = 0; i < s.size(); i++) {
            if (counter[s[i]] == 1) {
                return i;
            }
        }
        
        // 不存在唯一字符,返回 -1
        return -1;
    }
};
class Solution:
    def firstUniqChar(self, s: str) -> int:
        # Counter 可以直接统计字符串、列表等可迭代对象的元素频率
        # s = "leetcode"
        # cnt = Counter({'e': 3, 'l': 1, 't': 1, 'c': 1, 'o': 1, 'd': 1})
        cnt = Counter(s)
        print(cnt)

        # 如果想在for循环中同时获得列表的索引 i 和元素值 v
        # 可以使用枚举内置函数 enumerate()
        for i, v in enumerate(s):
            # 如果找到了某个字符出现的频率为 1
            if cnt[v] == 1:
                # 返回它的下标即可
                return i

        # 如果不存在,则返回 -1 
        return -1